home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / prsr_lib / iritprsb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  19.1 KB  |  623 lines

  1. /*****************************************************************************
  2. * Generic parser for the "Irit" solid modeller, in binary mode.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Nov. 1993   *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <math.h>
  10. #include <string.h>
  11. #include <setjmp.h>
  12. #include "irit_sm.h"
  13. #include "iritprsr.h"
  14. #include "allocate.h"
  15. #include "attribut.h"
  16. #include "irit_soc.h"
  17.  
  18. #define BIN_FILE_SYNC_STAMP    0x30106000
  19.  
  20. static int InputGetBinSync(FILE *f);
  21. static VoidPtr InputGetBinBlock(FILE *f, VoidPtr Block, int Size);
  22. static void OutputPutBinSync(FILE *f, int Type);
  23. static void OutputPutBinBlock(FILE *f, VoidPtr Block, int Size);
  24. static void IritPrsrGetBinObjectAux(void *f, IPObjectStruct *PObjParent);
  25. static IPPolygonStruct *InputGetBinPolys(FILE *f, int IsPolygon);
  26. static CagdCrvStruct *InputGetBinCurves(FILE *f);
  27. static CagdSrfStruct *InputGetBinSurfaces(FILE *f);
  28. static MatrixType *InputGetBinMatrix(FILE *f);
  29. static char *InputGetBinString(FILE *f);
  30. static IPObjectStruct **InputGetBinOList(FILE *f, int Len);
  31. static IPAttributeStruct *InputGetBinAttributes(FILE *f);
  32. static void OutputPutBinPolys(FILE *f, IPPolygonStruct *Pl);
  33. static void OutputPutBinCurves(FILE *f, CagdCrvStruct *Crv);
  34. static void OutputPutBinSurfaces(FILE *f, CagdSrfStruct *Srf);
  35. static void OutputPutBinAttributes(FILE *f, IPAttributeStruct *Attrs);
  36.  
  37. /*****************************************************************************
  38. *   Routine to get a sync stamp from input stream.                 *
  39. *   Returns zero if no input is available.                     *
  40. *****************************************************************************/
  41. static int InputGetBinSync(FILE *f)
  42. {
  43.     unsigned long l;
  44.  
  45.     InputGetBinBlock(f, (VoidPtr) &l, sizeof(long));
  46.  
  47.     if ((l & 0xffffff00) == BIN_FILE_SYNC_STAMP)
  48.     return l & 0xff;
  49.     else
  50.     return 0;
  51. }
  52.  
  53. /*****************************************************************************
  54. *   Routine to get a block of character from input stream.             *
  55. * If input returns EOF wait until new inputs arrive (can happen if reading   *
  56. * from a non io blocked socket).                         *
  57. *****************************************************************************/
  58. static VoidPtr InputGetBinBlock(FILE *f, VoidPtr Block, int Size)
  59. {
  60.     int c;
  61.     char
  62.     *p = (char *) Block;
  63.  
  64.     if (Block == NULL)
  65.         Block = IritMalloc(Size);
  66.  
  67.     while (Size-- > 0) {
  68.     if (_IritPrsrReadSocket) {
  69.         while ((c = SocClientReadCharNonBlock()) == EOF) {
  70.         IritSleep(10);
  71.         }
  72.     }
  73.     else
  74.         c = getc(f);
  75.  
  76.     *p++ = c;
  77.     }
  78.  
  79.     return Block;
  80. }
  81.  
  82. /*****************************************************************************
  83. *   Routine to put a sync stamp to output stream.                 *
  84. *****************************************************************************/
  85. static void OutputPutBinSync(FILE *f, int Type)
  86. {
  87.     unsigned long l = (Type | BIN_FILE_SYNC_STAMP);
  88.  
  89.     OutputPutBinBlock(f, (VoidPtr) &l, sizeof(long));
  90. }
  91.  
  92. /*****************************************************************************
  93. *   Routine to put a block of character to output stream.             *
  94. *****************************************************************************/
  95. static void OutputPutBinBlock(FILE *f, VoidPtr Block, int Size)
  96. {
  97.     if (_IritPrsrWriteSocket) {
  98.     SocServerWriteLine(Block, Size);
  99.     }
  100.     else
  101.         fwrite(Block, Size, 1, f);
  102. }
  103.  
  104. /*****************************************************************************
  105. * Routine to read one object from a given binary file, directly.         *
  106. * Note objects may be recursively defined.                     *
  107. *****************************************************************************/
  108. IPObjectStruct *IritPrsrGetBinObject(void *f)
  109. {
  110.     IPObjectStruct
  111.     *PObjParent = IPAllocObject("", IP_OBJ_UNDEF, NULL);
  112.  
  113.     /* If the following gain control and is non zero - its from error! */
  114.     if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
  115.     /* Error had occured (and will be reported). Return something... */
  116.     PObjParent -> ObjType = IP_OBJ_NUMERIC;
  117.     PObjParent -> U.R = 0.0;
  118.     return PObjParent;
  119.     }
  120.  
  121.     IritPrsrGetBinObjectAux(f, PObjParent);
  122.  
  123.     return IritPrsrProcessReadObject(PObjParent);
  124. }
  125.  
  126. /*****************************************************************************
  127. * Routine to read one object from a given binary file, directly.         *
  128. * Note objects may be recursively defined.                     *
  129. *****************************************************************************/
  130. static void IritPrsrGetBinObjectAux(void *f, IPObjectStruct *PObjParent)
  131. {
  132.     int Sync = InputGetBinSync(f);
  133.  
  134.     InputGetBinBlock(f, (VoidPtr) PObjParent, sizeof(IPObjectStruct));
  135.     PObjParent -> Pnext = NULL;
  136.     PObjParent -> Count = 1;
  137.  
  138.     if (PObjParent -> Attrs)
  139.     PObjParent -> Attrs = InputGetBinAttributes(f);
  140.  
  141.     switch (Sync) {
  142.     case IP_OBJ_POLY:
  143.         PObjParent -> U.Pl =
  144.         InputGetBinPolys(f, IP_IS_POLYGON_OBJ(PObjParent));
  145.         break;
  146.     case IP_OBJ_NUMERIC:
  147.         break;
  148.     case IP_OBJ_POINT:
  149.         break;
  150.     case IP_OBJ_VECTOR:
  151.         break;
  152.     case IP_OBJ_PLANE:
  153.         break;
  154.     case IP_OBJ_MATRIX:
  155.         PObjParent -> U.Mat = InputGetBinMatrix(f);
  156.         break;
  157.     case IP_OBJ_CURVE:
  158.         PObjParent -> U.Crvs = InputGetBinCurves(f);
  159.         break;
  160.     case IP_OBJ_SURFACE:
  161.         PObjParent -> U.Srfs = InputGetBinSurfaces(f);
  162.         break;
  163.     case IP_OBJ_STRING:
  164.         PObjParent -> U.Str = InputGetBinString(f);
  165.         break;
  166.     case IP_OBJ_LIST_OBJ:
  167.         PObjParent -> U.Lst.PObjList =
  168.         InputGetBinOList(f, PObjParent -> U.Lst.ListMaxLen);
  169.         break;
  170.     case IP_OBJ_CTLPT:
  171.         break;
  172.     default:
  173.         IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  174.     }
  175.  
  176.     if (Sync != IP_OBJ_LIST_OBJ &&
  177.     AttrGetObjectColor(PObjParent) == IP_ATTR_NO_COLOR)
  178.         AttrSetObjectColor(PObjParent, IP_LOAD_COLOR);
  179. }
  180.  
  181. /*****************************************************************************
  182. *   Routine to get a list of polys from bin input stream.             *
  183. *****************************************************************************/
  184. static IPPolygonStruct *InputGetBinPolys(FILE *f, int IsPolygon)
  185. {
  186.     int PSync;
  187.     IPPolygonStruct
  188.     *PHead = NULL,
  189.     *PTail = NULL;
  190.  
  191.     while ((PSync = InputGetBinSync(f)) == IP_OBJ_AUX_POLY) {
  192.     int VSync;
  193.     IPPolygonStruct
  194.         *Poly = IPAllocPolygon(0, 0, NULL, NULL);
  195.     IPVertexStruct *Vrtx,
  196.         *VTail = NULL;
  197.  
  198.     InputGetBinBlock(f, (VoidPtr) Poly, sizeof(IPPolygonStruct));
  199.     if (Poly -> Attrs)
  200.         Poly -> Attrs = InputGetBinAttributes(f);
  201.  
  202.     Poly -> PVertex = NULL;
  203.     while ((VSync = InputGetBinSync(f)) == IP_OBJ_AUX_VERTEX) {
  204.         Vrtx = IPAllocVertex(0, 0, NULL, NULL);
  205.         InputGetBinBlock(f, (VoidPtr) Vrtx, sizeof(IPVertexStruct));
  206.         if (Vrtx -> Attrs)
  207.         Vrtx -> Attrs = InputGetBinAttributes(f);
  208.  
  209.         if (Poly -> PVertex) {
  210.             VTail -> Pnext = Vrtx;
  211.         VTail = Vrtx;
  212.         }
  213.         else {
  214.         VTail = Poly -> PVertex = Vrtx;
  215.         }
  216.     }
  217.     if (_IritPrsrPolyListCirc)
  218.         VTail -> Pnext = Poly -> PVertex;
  219.     else
  220.         VTail -> Pnext = NULL;
  221.     if (VSync != IP_OBJ_AUX_END)
  222.         IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  223.  
  224.     if (IsPolygon) {
  225.         if (!IP_HAS_PLANE_POLY(Poly))
  226.         IritPrsrUpdatePolyPlane(Poly);
  227.  
  228.         IritPrsrUpdateVrtxNrml(Poly, Poly -> Plane);
  229.     }
  230.  
  231.     if (PHead) {
  232.         PTail -> Pnext = Poly;
  233.         PTail = Poly;
  234.     }
  235.     else {
  236.         PHead = PTail = Poly;
  237.     }
  238.     }
  239.     if (PSync != IP_OBJ_AUX_END)
  240.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  241.  
  242.     if (PTail)
  243.     PTail -> Pnext = NULL;
  244.  
  245.     if (PHead == NULL)
  246.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  247.  
  248.     return PHead;
  249. }
  250.  
  251. /*****************************************************************************
  252. *   Routine to get a list of curves from bin input stream.             *
  253. *****************************************************************************/
  254. static CagdCrvStruct *InputGetBinCurves(FILE *f)
  255. {
  256.     int i, Sync, Size;
  257.     CagdCrvStruct *Crv,
  258.     *CHead = NULL,
  259.     *CTail = NULL;
  260.  
  261.     while ((Sync = InputGetBinSync(f)) == IP_OBJ_AUX_CURVE) {
  262.     Crv = (CagdCrvStruct *) IritMalloc(sizeof(CagdCrvStruct));
  263.     InputGetBinBlock(f, (VoidPtr) Crv, sizeof(CagdCrvStruct));
  264.     Size = sizeof(CagdRType) * Crv -> Length;
  265.  
  266.     for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType);
  267.          i <= CAGD_NUM_OF_PT_COORD(Crv -> PType);
  268.          i++) {
  269.         Crv -> Points[i] = (CagdRType *) IritMalloc(Size);
  270.         InputGetBinBlock(f, (VoidPtr) (Crv -> Points[i]), Size);
  271.     }
  272.  
  273.     for (i = CAGD_NUM_OF_PT_COORD(Crv -> PType) + 1;
  274.          i <= CAGD_MAX_PT_COORD;
  275.          i++)
  276.         Crv -> Points[i] = NULL;
  277.  
  278.     if (Crv -> GType == CAGD_CBSPLINE_TYPE) {
  279.         Size = sizeof(CagdRType) * (Crv -> Length + Crv -> Order);
  280.         Crv -> KnotVector = (CagdRType *) IritMalloc(Size);
  281.         InputGetBinBlock(f, (VoidPtr) (Crv -> KnotVector), Size);
  282.     }
  283.  
  284.     if (CHead == NULL) {
  285.         CHead = CTail = Crv;
  286.     }
  287.     else {
  288.         CTail -> Pnext = Crv;
  289.         CTail = Crv;
  290.     }
  291.     }
  292.     if (Sync != IP_OBJ_AUX_END)
  293.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  294.  
  295.     if (CHead == NULL)
  296.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  297.  
  298.     return CHead;
  299. }
  300.  
  301. /*****************************************************************************
  302. *   Routine to get a list of surfaces from bin input stream.             *
  303. *****************************************************************************/
  304. static CagdSrfStruct *InputGetBinSurfaces(FILE *f)
  305. {
  306.     int i, Sync, Size;
  307.     CagdSrfStruct *Srf,
  308.     *SHead = NULL,
  309.     *STail = NULL;
  310.  
  311.     while ((Sync = InputGetBinSync(f)) == IP_OBJ_AUX_SURFACE) {
  312.     Srf = (CagdSrfStruct *) IritMalloc(sizeof(CagdSrfStruct));
  313.     InputGetBinBlock(f, (VoidPtr) Srf, sizeof(CagdSrfStruct));
  314.     Size = sizeof(CagdRType) * Srf -> ULength * Srf -> VLength;
  315.  
  316.     for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType);
  317.          i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  318.          i++) {
  319.         Srf -> Points[i] = (CagdRType *) IritMalloc(Size);
  320.         InputGetBinBlock(f, (VoidPtr) (Srf -> Points[i]), Size);
  321.     }
  322.  
  323.     for (i = CAGD_NUM_OF_PT_COORD(Srf -> PType) + 1;
  324.          i <= CAGD_MAX_PT_COORD;
  325.          i++)
  326.         Srf -> Points[i] = NULL;
  327.  
  328.     if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
  329.         Size = sizeof(CagdRType) * (Srf -> ULength + Srf -> UOrder);
  330.         Srf -> UKnotVector = (CagdRType *) IritMalloc(Size);
  331.         InputGetBinBlock(f, (VoidPtr) (Srf -> UKnotVector), Size);
  332.         Size = sizeof(CagdRType) * (Srf -> VLength + Srf -> VOrder);
  333.         Srf -> VKnotVector = (CagdRType *) IritMalloc(Size);
  334.         InputGetBinBlock(f, (VoidPtr) (Srf -> VKnotVector), Size);
  335.     }
  336.  
  337.     if (SHead == NULL) {
  338.         SHead = STail = Srf;
  339.     }
  340.     else {
  341.         STail -> Pnext = Srf;
  342.         STail = Srf;
  343.     }
  344.     }
  345.     if (Sync != IP_OBJ_AUX_END || SHead == NULL)
  346.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  347.  
  348.     return SHead;
  349. }
  350.  
  351. /*****************************************************************************
  352. *   Routine to get a matrix from bin input stream.                 *
  353. *****************************************************************************/
  354. static MatrixType *InputGetBinMatrix(FILE *f)
  355. {
  356.     MatrixType *Mat;
  357.  
  358.     if (InputGetBinSync(f) != IP_OBJ_AUX_MATRIX)
  359.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  360.     Mat = (MatrixType *) IritMalloc(sizeof(MatrixType));
  361.     InputGetBinBlock(f, (VoidPtr) Mat, sizeof(MatrixType));
  362.  
  363.     return Mat;
  364. }
  365.  
  366. /*****************************************************************************
  367. *   Routine to get a string from bin input stream.                 *
  368. *****************************************************************************/
  369. static char *InputGetBinString(FILE *f)
  370. {
  371.     long Len;
  372.     char *Str;
  373.  
  374.     if (InputGetBinSync(f) != IP_OBJ_AUX_STRING)
  375.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  376.     InputGetBinBlock(f, (VoidPtr) &Len, sizeof(long));
  377.     Str = (char *) IritMalloc(Len);
  378.     InputGetBinBlock(f, (VoidPtr) Str, Len);
  379.     return Str;
  380. }
  381.  
  382. /*****************************************************************************
  383. *   Routine to get an object list from bin input stream.             *
  384. *****************************************************************************/
  385. static IPObjectStruct **InputGetBinOList(FILE *f, int Len)
  386. {
  387.     int i;
  388.     struct IPObjectStruct *PTmp,
  389.     **PObjList = (IPObjectStruct **)
  390.         IritMalloc(Len * sizeof(IPObjectStruct *));
  391.  
  392.     if (InputGetBinSync(f) != IP_OBJ_AUX_OLST)
  393.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  394.     InputGetBinBlock(f, (VoidPtr) PObjList, Len * sizeof(IPObjectStruct *));
  395.  
  396.     for (i = 0; i < Len && PObjList[i] != NULL; i++) {
  397.     PTmp = IPAllocObject("", IP_OBJ_UNDEF, NULL);
  398.     IritPrsrGetBinObjectAux(f, PTmp);
  399.     PObjList[i] = PTmp;
  400.     }
  401.     if (i < Len - 1)
  402.     PObjList[i] = NULL;
  403.  
  404.     return PObjList;
  405. }
  406.  
  407. /*****************************************************************************
  408. *   Routine to get a list of attributes from bin input stream.             *
  409. *****************************************************************************/
  410. static IPAttributeStruct *InputGetBinAttributes(FILE *f)
  411. {
  412.     int Sync;
  413.     IPAttributeStruct *Attr,
  414.     *ATail = NULL,
  415.     *AHead = NULL;
  416.  
  417.     while ((Sync = InputGetBinSync(f)) == IP_OBJ_AUX_ATTR) {
  418.     long Len;
  419.  
  420.     Attr = (IPAttributeStruct *) IritMalloc(sizeof(IPAttributeStruct));
  421.     InputGetBinBlock(f, (VoidPtr) Attr, sizeof(IPAttributeStruct));
  422.     InputGetBinBlock(f, (VoidPtr) &Len, sizeof(long));
  423.     Attr -> Name = IritMalloc(Len);
  424.     InputGetBinBlock(f, (VoidPtr) (Attr -> Name), Len);
  425.     if (Attr -> Type == IP_ATTR_STR) {
  426.         if (InputGetBinSync(f) != IP_OBJ_AUX_STRING)
  427.         IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  428.         InputGetBinBlock(f, (VoidPtr) &Len, sizeof(long));
  429.         Attr -> U.Str = IritMalloc(Len);
  430.         InputGetBinBlock(f, (VoidPtr) (Attr -> U.Str), Len);
  431.     }
  432.  
  433.     if (AHead) {
  434.         ATail -> Pnext = Attr;
  435.         ATail = Attr;
  436.     }
  437.     else {
  438.         ATail = AHead = Attr;
  439.     }
  440.     }
  441.     if (Sync != IP_OBJ_AUX_END)
  442.     IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  443.  
  444.     return AHead;
  445. }
  446.  
  447. /*****************************************************************************
  448. * Routine to write one object to a given binary file, directly.             *
  449. * Note objects may be recursively defined.                     *
  450. *****************************************************************************/
  451. void IritPrsrPutBinObject(void *f, IPObjectStruct *PObj)
  452. {
  453.     int i;
  454.     long Len;
  455.     IPObjectStruct *PTmp;
  456.  
  457.     /* If the following gain control and is non zero - its from error! */
  458.     if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
  459.     /* Error had occured (and will be reported). */
  460.     return;
  461.     }
  462.  
  463.     OutputPutBinSync(f, PObj -> ObjType);
  464.     OutputPutBinBlock(f, (VoidPtr) PObj, sizeof(IPObjectStruct));
  465.     if (PObj -> Attrs != NULL)
  466.     OutputPutBinAttributes(f, PObj -> Attrs);
  467.  
  468.     switch (PObj -> ObjType) {
  469.     case IP_OBJ_POLY:
  470.         OutputPutBinPolys(f, PObj -> U.Pl);
  471.         break;
  472.     case IP_OBJ_NUMERIC:
  473.         break;
  474.     case IP_OBJ_POINT:
  475.         break;
  476.     case IP_OBJ_VECTOR:
  477.         break;
  478.     case IP_OBJ_PLANE:
  479.         break;
  480.     case IP_OBJ_MATRIX:
  481.         OutputPutBinSync(f, IP_OBJ_AUX_MATRIX);
  482.         OutputPutBinBlock(f, (VoidPtr) (*PObj -> U.Mat),
  483.                   sizeof(MatrixType));
  484.         break;
  485.     case IP_OBJ_CURVE:
  486.         OutputPutBinCurves(f, PObj -> U.Crvs);
  487.         break;
  488.     case IP_OBJ_SURFACE:
  489.         OutputPutBinSurfaces(f, PObj -> U.Srfs);
  490.         break;
  491.     case IP_OBJ_STRING:
  492.         OutputPutBinSync(f, IP_OBJ_AUX_STRING);
  493.         Len = strlen(PObj -> U.Str) + 1;
  494.         OutputPutBinBlock(f, (VoidPtr) &Len, sizeof(long));
  495.         OutputPutBinBlock(f, (VoidPtr) (PObj -> U.Str), Len);
  496.         break;
  497.     case IP_OBJ_LIST_OBJ:
  498.         OutputPutBinSync(f, IP_OBJ_AUX_OLST);
  499.         OutputPutBinBlock(f, (VoidPtr) PObj -> U.Lst.PObjList,
  500.             sizeof(IPObjectStruct *) * PObj -> U.Lst.ListMaxLen);
  501.         for (i = 0;
  502.          i < PObj -> U.Lst.ListMaxLen &&
  503.          (PTmp = ListObjectGet(PObj, i)) != NULL;
  504.          i++) {
  505.         IritPrsrPutBinObject(f, PTmp);
  506.         }
  507.         break;
  508.     case IP_OBJ_CTLPT:
  509.         break;
  510.     default:
  511.         IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
  512.     }
  513. }
  514.  
  515. /*****************************************************************************
  516. *   Routine to put a list of polys to bin output stream.             *
  517. *****************************************************************************/
  518. static void OutputPutBinPolys(FILE *f, IPPolygonStruct *Pl)
  519. {
  520.     for (; Pl != NULL; Pl = Pl -> Pnext) {
  521.     IPVertexStruct
  522.         *V = Pl -> PVertex;
  523.  
  524.     OutputPutBinSync(f, IP_OBJ_AUX_POLY);
  525.     OutputPutBinBlock(f, (VoidPtr) Pl, sizeof(IPPolygonStruct));
  526.     if (Pl -> Attrs != NULL)
  527.         OutputPutBinAttributes(f, Pl -> Attrs);
  528.  
  529.     do {
  530.         OutputPutBinSync(f, IP_OBJ_AUX_VERTEX);
  531.         OutputPutBinBlock(f, (VoidPtr) V, sizeof(IPVertexStruct));
  532.         if (V -> Attrs != NULL)
  533.         OutputPutBinAttributes(f, V -> Attrs);
  534.         V = V -> Pnext;
  535.     }
  536.     while (V != NULL && V != Pl -> PVertex);
  537.     OutputPutBinSync(f, IP_OBJ_AUX_END);
  538.     }
  539.     OutputPutBinSync(f, IP_OBJ_AUX_END);
  540. }
  541.  
  542. /*****************************************************************************
  543. *   Routine to put a list of curves to bin output stream.             *
  544. *****************************************************************************/
  545. static void OutputPutBinCurves(FILE *f, CagdCrvStruct *Crv)
  546. {
  547.     for ( ; Crv != NULL; Crv = Crv -> Pnext) {
  548.     int i,
  549.         Size = sizeof(CagdRType) * Crv -> Length;
  550.  
  551.     OutputPutBinSync(f, IP_OBJ_AUX_CURVE);
  552.     OutputPutBinBlock(f, (VoidPtr) Crv, sizeof(CagdCrvStruct));
  553.  
  554.     for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType);
  555.          i <= CAGD_NUM_OF_PT_COORD(Crv -> PType);
  556.          i++) {
  557.         OutputPutBinBlock(f, (VoidPtr) (Crv -> Points[i]), Size);
  558.     }
  559.  
  560.     if (Crv -> GType == CAGD_CBSPLINE_TYPE) {
  561.         Size = sizeof(CagdRType) * (Crv -> Length + Crv -> Order);
  562.         OutputPutBinBlock(f, (VoidPtr) (Crv -> KnotVector), Size);
  563.     }
  564.     }
  565.     OutputPutBinSync(f, IP_OBJ_AUX_END);
  566. }
  567.  
  568. /*****************************************************************************
  569. *   Routine to put a list of surfaces to bin output stream.             *
  570. *****************************************************************************/
  571. static void OutputPutBinSurfaces(FILE *f, CagdSrfStruct *Srf)
  572. {
  573.     for ( ; Srf != NULL; Srf = Srf -> Pnext) {
  574.     int i,
  575.         Size = sizeof(CagdRType) * Srf -> ULength * Srf -> VLength;
  576.  
  577.     OutputPutBinSync(f, IP_OBJ_AUX_SURFACE);
  578.     OutputPutBinBlock(f, (VoidPtr) Srf, sizeof(CagdSrfStruct));
  579.  
  580.     for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType);
  581.          i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  582.          i++) {
  583.         OutputPutBinBlock(f, (VoidPtr) (Srf -> Points[i]), Size);
  584.     }
  585.  
  586.     if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
  587.         Size = sizeof(CagdRType) * (Srf -> ULength + Srf -> UOrder);
  588.         OutputPutBinBlock(f, (VoidPtr) (Srf -> UKnotVector), Size);
  589.         Size = sizeof(CagdRType) * (Srf -> VLength + Srf -> VOrder);
  590.         OutputPutBinBlock(f, (VoidPtr) (Srf -> VKnotVector), Size);
  591.     }
  592.     }
  593.     OutputPutBinSync(f, IP_OBJ_AUX_END);
  594. }
  595.  
  596. /*****************************************************************************
  597. *   Routine to put a list of attributes to bin output stream.             *
  598. *****************************************************************************/
  599. static void OutputPutBinAttributes(FILE *f, IPAttributeStruct *Attrs)
  600. {
  601.     for ( ; Attrs != NULL; Attrs = Attrs -> Pnext) {
  602.     if (Attrs -> Type == IP_ATTR_INT ||
  603.         Attrs -> Type == IP_ATTR_REAL ||
  604.         Attrs -> Type == IP_ATTR_STR) {
  605.         long Len = strlen(Attrs -> Name) + 1;
  606.  
  607.         OutputPutBinSync(f, IP_OBJ_AUX_ATTR);
  608.         OutputPutBinBlock(f, (VoidPtr) Attrs, sizeof(IPAttributeStruct));
  609.         OutputPutBinBlock(f, (VoidPtr) &Len, sizeof(long));
  610.         OutputPutBinBlock(f, (VoidPtr) (Attrs -> Name), Len);
  611.  
  612.         if (Attrs -> Type == IP_ATTR_STR) {
  613.         Len = strlen(Attrs -> U.Str) + 1;
  614.  
  615.         OutputPutBinSync(f, IP_OBJ_AUX_STRING);
  616.         OutputPutBinBlock(f, (VoidPtr) &Len, sizeof(long));
  617.         OutputPutBinBlock(f, (VoidPtr) (Attrs -> U.Str), Len);
  618.         }    
  619.     }
  620.     }
  621.     OutputPutBinSync(f, IP_OBJ_AUX_END);
  622. }
  623.